home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Peter Lewis / PNL Libraries / MyFastFind.p < prev    next >
Encoding:
Text File  |  1994-08-27  |  3.5 KB  |  150 lines  |  [TEXT/PJMM]

  1. unit MyFastFind;
  2.  
  3. interface
  4.  
  5.     function SetFastFindSize (p: ptr; siz: longInt): OSErr;
  6.     function SetFastFindWord (p: ptr; theWord: str63): OSErr;
  7.     function SetFastFindFile (p: ptr; refnum: integer): OSErr;
  8.     function StartFastFind (p: ptr): OSErr;
  9.     function FastFind (p: ptr): longInt;
  10.     function OldFastFind (p: ptr): longInt;
  11.  
  12. implementation
  13.  
  14.     type
  15.         dataArray = packed array[1..1000000] of char;
  16.         wordType = str63;
  17.         findRecord = record
  18.                 size: longInt;
  19.                 datap: ^dataArray;
  20.                 word: wordType;
  21.                 rn: integer;
  22.                 filelen, pos, count, data_index: longInt;
  23.                 skip: packed array[char] of byte;
  24.                 data: integer;
  25.             end;
  26.         findPtr = ^findRecord;
  27.  
  28.     function UpCase (ch: char): char;
  29.     inline
  30.         $301F, $0C00, $0061, $6500, $000E, $0C00, $007B, $6400, $0006, $0400, $0020, $3E80;
  31.  
  32.     function SetFastFindSize (p: ptr; siz: longInt): OSErr;
  33.     begin
  34.         with findPtr(p)^ do begin
  35.             size := siz - SizeOf(findRecord);
  36.             datap := @data;
  37.             if size > 256 then
  38.                 SetFastFindSize := noErr
  39.             else
  40.                 SetFastFindSize := paramErr;
  41.         end;
  42.     end;
  43.  
  44.     function SetFastFindWord (p: ptr; theWord: str63): OSErr;
  45.         var
  46.             i: integer;
  47.     begin
  48.         with findPtr(p)^ do begin
  49.             word := theWord;
  50.             for i := 0 to 255 do
  51.                 skip[chr(i)] := length(word);
  52.             for i := 1 to length(word) do begin
  53.                 word[i] := UpCase(word[i]);
  54.                 skip[word[i]] := length(word) - i;
  55.             end;
  56.         end;
  57.         SetFastFindWord := noErr;
  58.     end;
  59.  
  60.     function SetFastFindFile (p: ptr; refnum: integer): OSErr;
  61.         var
  62.             oe: OSErr;
  63.     begin
  64.         with findPtr(p)^ do begin
  65.             rn := refnum;
  66.             oe := GetEOF(rn, filelen);
  67.             if oe = noErr then
  68.                 oe := GetFPos(rn, pos);
  69.             if oe = noErr then begin
  70.                 count := size;
  71.                 oe := FSRead(rn, count, ptr(datap));
  72.                 if (oe = eofErr) and (count > 0) then
  73.                     oe := noErr;
  74.             end;
  75.         end;
  76.         SetFastFindFile := oe;
  77.     end;
  78.  
  79.     function StartFastFind (p: ptr): OSErr;
  80.     begin
  81.         with findPtr(p)^ do begin
  82.             data_index := length(word);
  83.             if data_index > count then
  84.                 StartFastFind := -1
  85.             else
  86.                 StartFastFind := noErr;
  87.         end;
  88.     end;
  89.  
  90.     function OldFastFind (p: ptr): longInt;
  91.         var
  92.             oe: OSErr;
  93.             ch: char;
  94.             amount: 0..63;
  95.             wi: integer;
  96.     begin
  97.         with findPtr(p)^ do begin
  98.             oe := noErr;
  99.             wi := length(word);
  100.             while (oe = noErr) and (wi <> 0) and (pos + data_index < filelen) do begin
  101. { data_index is the last character in data that we are checking now }
  102.  
  103.                 if data_index > count then begin
  104.                     amount := count - (data_index - length(word));
  105.                     pos := pos + count - amount;
  106.                     BlockMove(@datap^[data_index - length(word) + 1], ptr(datap), amount);
  107.                     data_index := length(word);
  108.                     count := size - amount;
  109.                     oe := FSRead(rn, count, @datap^[amount + 1]);
  110.                     if oe = eofErr then
  111.                         oe := noErr;
  112.                     count := count + amount;
  113.                 end;
  114.                 if (data_index > count) and (oe = noErr) then
  115.                     oe := -1;
  116.                 if oe = noErr then begin
  117.                     repeat
  118.                         ch := UpCase(datap^[data_index]);
  119.                         if ch = word[wi] then begin
  120.                             data_index := data_index - 1;
  121.                             wi := wi - 1;
  122.                             if wi = 0 then
  123.                                 leave;
  124.                         end
  125.                         else begin
  126. {    data_index := data_index + Max(length(word) - wi + 1, skip[ch]);}
  127.                             if length(word) - wi + 1 > skip[ch] then
  128.                                 data_index := data_index + length(word) - wi + 1
  129.                             else
  130.                                 data_index := data_index + skip[ch];
  131.                             wi := length(word);
  132.                             if data_index > count then
  133.                                 leave;
  134.                         end;
  135.                     until false;
  136.                 end;
  137.             end;
  138.             if wi <> 0 then begin
  139.                 if oe >= 0 then
  140.                     oe := -1;
  141.                 OldFastFind := oe;
  142.             end
  143.             else begin
  144.                 OldFastFind := pos + data_index;
  145.                 data_index := data_index + length(word) + 1;
  146.             end;
  147.         end;
  148.     end;
  149.  
  150. end.